import globals from 'globals';
import js from '@eslint/js';
import ts from 'typescript-eslint';
import vue from 'eslint-plugin-vue';
import stylistic from '@stylistic/eslint-plugin';

export default [
	//region 全局配置
	{
		ignores:[
			'static/',
		]
	},
	{
		languageOptions:{
			globals:{
				...globals.node,
				...globals.browser,
				...globals.es2021,
			},
		},
		linterOptions:{
			noInlineConfig:true,
			reportUnusedDisableDirectives:'error',
		},
	},
	//endregion
	//region js规则
	js.configs.recommended,
	{
		rules:{
			//禁止var
			'no-var':'error',
			//禁止使用arguments,而使用剩余参数
			'prefer-rest-params':'error',
			//比较相等用 ===
			'eqeqeq':['error','always',{
				null:'ignore',
			}],
			//条件测试不能用常量表达式(循环除外)
			'no-constant-condition':['error',{
				checkLoops:false,
			}],
		},
	},
	//endregion
	//region ts规则
	...ts.configs.recommended.map((config) => {
		return {
			...config,
			files:[
				'**/*.ts',
				'**/*.vue',
			],
		};
	}),
	{
		files:[
			'**/*.ts',
			'**/*.vue',
		],
		rules:{
			'@typescript-eslint/no-this-alias':'off',
			'@typescript-eslint/no-empty-function':'off',
			'@typescript-eslint/no-explicit-any':'off',
			'@typescript-eslint/ban-ts-comment':'off',
			'@typescript-eslint/no-non-null-assertion':'off',
			'@typescript-eslint/no-unused-expressions':'off',
		},
	},
	//endregion
	//region vue规则
	...vue.configs['flat/recommended'].map((config) => {
		return {
			...config,
			files:[
				'**/*.vue',
			],
		};
	}),
	{
		files:[
			'**/*.vue',
		],
		languageOptions:{
			parserOptions:{
				ecmaVersion:'latest',
				sourceType:'module',
				parser:{
					js:'espree',
					ts:'@typescript-eslint/parser',
				},
			},
		},
		plugins:{
			'@typescript-eslint':ts.plugin,
		},
		rules:{
			//prop默认值
			'vue/require-default-prop':'off',
			//多单词组件名
			'vue/multi-word-component-names':'off',
			//组件内容换行
			'vue/singleline-html-element-content-newline':'off',
			//插值符 {{ }} 内无空格
			'vue/mustache-interpolation-spacing':['error','never'],
			//tab缩进
			'vue/html-indent':['error','tab'],
			//标签名空格
			'vue/html-closing-bracket-spacing':['error',{
				startTag:'never',
				endTag:'never',
				selfClosingTag:'never',
			}],
			//一行只写一个属性
			'vue/max-attributes-per-line':'error',
			//属性必须换行写
			'vue/first-attribute-linebreak':'error',
			//标签内多个元素必须换行
			'vue/multiline-html-element-content-newline':'error',
			//属性必须中划线命名
			'vue/attribute-hyphenation':'error',
			//组件命名规范PascalCase
			'vue/component-definition-name-casing':'error',
			//标签 > 换行规则
			'vue/html-closing-bracket-newline':'error',
			//必须有结束标签
			'vue/html-end-tags':'error',
			//属性值用双引号包裹
			'vue/html-quotes':'error',
			//标签尽量自闭合
			'vue/html-self-closing':'error',
			//禁止连续多个空格
			'vue/no-multi-spaces':'error',
			//禁止 = 周围的空格
			'vue/no-spaces-around-equal-signs-in-attribute':'error',
			//禁止在嵌套中使用重复变量名
			'vue/no-template-shadow':'error',
			//单文件只能有一个根元素
			'vue/one-component-per-file':'error',
			//属性命名规范camelCase
			'vue/prop-name-casing':'error',
			//必现声明事件
			'vue/require-explicit-emits':'error',
			//属性必须定义类型
			'vue/require-prop-types':'error',
			//v-bind简写
			'vue/v-bind-style':'error',
			//事件在模板中用中划线风格
			'vue/v-on-event-hyphenation':['error', 'always', {
				autofix:true,
			}],
			//v-on简写
			'vue/v-on-style':'error',
			//v-slot简写
			'vue/v-slot-style':'error',
			//属性顺序
			'vue/attributes-order':'error',
			//顶级 template, script, style顺序
			'vue/block-order':'error',
			'vue/no-lone-template':'error',
			//作用域插槽只允许一个参数
			'vue/no-multiple-slot-args':'error',
			//组件选项顺序
			'vue/order-in-components':'error',
			//禁止模板中的this
			'vue/this-in-template':'error',
		},
	},
	//endregion
	//region 代码风格
	stylistic.configs.customize({
		//缩进
		indent:'tab',
		//字符串
		quotes:'single',
		//分号
		semi:true,
		jsx:true,
		//箭头函数
		arrowParens:true,
		//大括号样式
		braceStyle:'1tbs',
		//块之间空格
		blockSpacing:false,
		//对象字面值属性是否加引号
		quoteProps:'as-needed',
		//尾逗号
		commaDangle:'always-multiline',
	}),
	{
		plugins:{
			'@stylistic':stylistic,
		},
		rules:{
			//注释中一致的空格
			'@stylistic/spaced-comment':'off',
			//不允许花括号内出现多余的空格
			'@stylistic/object-curly-spacing':['error','never'],
			//语句块前不能有多余的空格
			'@stylistic/space-before-blocks':['error','never'],
			//函数的参数括号前不能有多余的空格
			'@stylistic/space-before-function-paren':['error',{
				anonymous:'never',
				named:'never',
				asyncArrow:'always',
			}],
			//对象字面值,键值对和冒号间不能有空格
			'@stylistic/key-spacing':['error',{
				beforeColon:false,
				afterColon:false,
			}],
			//逗号前后不能有空格
			'@stylistic/comma-spacing':['error',{
				before:false,
				after:true,
			}],
			//关键字周围的空格
			'@stylistic/keyword-spacing':['error',{
				before:true,
				after:true,
				overrides:{
					switch:{after:false,before:false},
					if:{after:false,before:false},
					else:{after:false,before:false},
					for:{after:false,before:false},
					do:{after:false,before:false},
					while:{after:false,before:false},
					default:{after:true,before:false},
					this:{after:false,before:false},
					try:{after:false,before:false},
					catch:{after:false,before:false},
					finally:{after:false,before:false},
					await:{after:false,before:false},
				}
			}],
			//生成器函数,*前不能有空格,*后面必须有空格
			'@stylistic/generator-star-spacing':['error',{
				before:false,
				after:true,
			}],
			//yield*表达式,*前不能有空格,*后面必须有空格
			'@stylistic/yield-star-spacing':['error',{
				before:false,
				after:true,
			}],
			//类型声明周围的空格
			'@stylistic/type-annotation-spacing':['error',{
				before:false,
				after:false,
				overrides:{
					arrow:{
						before:true,
						after:true,
					},
				},
			}],
			//文件末尾追加换行符
			'@stylistic/eol-last':['error','never'],
			//缩进
			'@stylistic/indent':['error','tab',{
				ArrayExpression:1,
				CallExpression:{arguments:1},
				flatTernaryExpressions:false,
				FunctionDeclaration:{body:1,parameters:1},
				FunctionExpression:{body:1,parameters:1},
				ignoreComments:true,
				ImportDeclaration:1,
				MemberExpression:1,
				ObjectExpression:1,
				offsetTernaryExpressions:false,
				outerIIFEBody:1,
				SwitchCase:1,
				VariableDeclarator:1,
				ignoredNodes:[
					"TemplateLiteral *",
					"JSXElement",
					"JSXElement > *",
					"JSXAttribute",
					"JSXIdentifier",
					"JSXNamespacedName",
					"JSXMemberExpression",
					"JSXSpreadAttribute",
					"JSXExpressionContainer",
					"JSXOpeningElement",
					"JSXClosingElement",
					"JSXFragment",
					"JSXOpeningFragment",
					"JSXClosingFragment",
					"JSXText",
					"JSXEmptyExpression",
					"JSXSpreadChild",
					"TSUnionType",
					"TSIntersectionType",
					"TSTypeParameterInstantiation",
					"FunctionExpression > .params[decorators.length > 0]",
					"FunctionExpression > .params > :matches(Decorator, :not(:first-child))",
					"ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"
				],
			}],
		},
	},
	//endregion
];